{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "ba46e3eb-5bdc-43d5-a232-24638195ce94",
   "metadata": {},
   "outputs": [],
   "source": [
    "import torch\n",
    "import torch.nn as nn\n",
    "import torch.optim as optim\n",
    "import torch.nn.functional as F\n",
    "import torchvision.transforms as transforms\n",
    "from torch.utils.data import DataLoader\n",
    "from torch.cuda.amp import GradScaler, autocast\n",
    "from tqdm import tqdm\n",
    "from PIL import Image\n",
    "import time  # 导入time模块\n",
    "import matplotlib.pyplot as plt  # 导入matplotlib模块"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "9660980e-8ba1-45ff-a47b-9eefb25cc8a4",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 定义数据集路径\n",
    "train_label_path = \"data_sort/train/label.txt\"\n",
    "test_label_path = \"data_sort/test/label.txt\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "f0f63851-9f97-404f-85ec-a35f6f3af503",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 读取标签和数据\n",
    "labels = {}\n",
    "train_data = []\n",
    "test_data = []"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "6093e56b-d78a-4b85-9263-17e50e502512",
   "metadata": {},
   "outputs": [],
   "source": [
    "with open(train_label_path, 'r') as f:\n",
    "    lines = f.readlines()\n",
    "    for line in lines:\n",
    "        k_v = line.split(' ')\n",
    "        train_data.append(k_v[0])\n",
    "        labels[k_v[0]] = k_v[1]\n",
    "\n",
    "class GetTrainLoader(torch.utils.data.Dataset):\n",
    "    def __init__(self):\n",
    "        self.data = train_data\n",
    "        self.label = labels\n",
    "        self.transform_train = transforms.Compose([\n",
    "            transforms.Resize((135, 240)),\n",
    "            transforms.ToTensor(),\n",
    "        ])\n",
    "\n",
    "    def __getitem__(self, index):\n",
    "        im_id = self.data[index]\n",
    "        image = Image.open(im_id)\n",
    "        image = image.crop([300, 80, 1620, 950])\n",
    "        image = self.transform_train(image)\n",
    "        label = int(self.label[im_id])\n",
    "        return image, label, im_id\n",
    "\n",
    "    def __len__(self):\n",
    "        return len(self.data)\n",
    "\n",
    "with open(test_label_path, 'r') as f:\n",
    "    lines = f.readlines()\n",
    "    for line in lines:\n",
    "        k_v = line.split(' ')\n",
    "        test_data.append(k_v[0])\n",
    "        labels[k_v[0]] = k_v[1]\n",
    "\n",
    "class GetTestLoader(torch.utils.data.Dataset):\n",
    "    def __init__(self):\n",
    "        self.data = test_data\n",
    "        self.label = labels\n",
    "        self.transform_test = transforms.Compose([\n",
    "            transforms.Resize((135, 240)),\n",
    "            transforms.ToTensor(),\n",
    "        ])\n",
    "\n",
    "    def __getitem__(self, index):\n",
    "        im_id = self.data[index]\n",
    "        image = Image.open(im_id)\n",
    "        image = image.crop([300, 80, 1620, 950])\n",
    "        image = self.transform_test(image)\n",
    "        label = int(self.label[im_id])\n",
    "        return image, label, im_id\n",
    "\n",
    "    def __len__(self):\n",
    "        return len(self.data)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "73128ffb-9769-43be-a300-1e7a8a20f90d",
   "metadata": {},
   "outputs": [],
   "source": [
    "class ResidualBlock(nn.Module):\n",
    "    def __init__(self, inchannel, outchannel, stride=1):\n",
    "        super(ResidualBlock, self).__init__()\n",
    "        self.left = nn.Sequential(\n",
    "            nn.Conv2d(inchannel, outchannel, kernel_size=3, stride=stride, padding=1, bias=False),\n",
    "            nn.BatchNorm2d(outchannel),\n",
    "            nn.ReLU(inplace=True),\n",
    "            nn.Conv2d(outchannel, outchannel, kernel_size=3, stride=1, padding=1, bias=False),\n",
    "            nn.BatchNorm2d(outchannel)\n",
    "        )\n",
    "        self.shortcut = nn.Sequential()\n",
    "        if stride != 1 or inchannel != outchannel:\n",
    "            self.shortcut = nn.Sequential(\n",
    "                nn.Conv2d(inchannel, outchannel, kernel_size=1, stride=stride, bias=False),\n",
    "                nn.BatchNorm2d(outchannel)\n",
    "            )\n",
    "            \n",
    "    def forward(self, x):\n",
    "        out = self.left(x)\n",
    "        out = out + self.shortcut(x)\n",
    "        out = F.relu(out)\n",
    "        return out\n",
    "\n",
    "class ResNet(nn.Module):\n",
    "    def __init__(self, ResidualBlock, num_classes=5):\n",
    "        super(ResNet, self).__init__()\n",
    "        self.inchannel = 64\n",
    "        self.conv1 = nn.Sequential(\n",
    "            nn.Conv2d(3, 64, kernel_size=5, stride=1, padding=1, bias=False),\n",
    "            nn.BatchNorm2d(64),\n",
    "            nn.ReLU()\n",
    "        )\n",
    "        self.layer1 = self.make_layer(ResidualBlock, 64, 2, stride=1)\n",
    "        self.layer2 = self.make_layer(ResidualBlock, 128, 2, stride=2)\n",
    "        self.layer3 = self.make_layer(ResidualBlock, 256, 2, stride=2)      \n",
    "        self.layer4 = self.make_layer(ResidualBlock, 512, 2, stride=2)        \n",
    "        self.fc = nn.Linear(14336, num_classes)\n",
    "        \n",
    "    def make_layer(self, block, channels, num_blocks, stride):\n",
    "        strides = [stride] + [1] * (num_blocks - 1)\n",
    "        layers = []\n",
    "        for stride in strides:\n",
    "            layers.append(block(self.inchannel, channels, stride))\n",
    "            self.inchannel = channels\n",
    "        return nn.Sequential(*layers)\n",
    "    \n",
    "    def forward(self, x):\n",
    "        out = self.conv1(x)\n",
    "        out = self.layer1(out)\n",
    "        out = self.layer2(out)\n",
    "        out = self.layer3(out)\n",
    "        out = self.layer4(out)\n",
    "        out = F.avg_pool2d(out, 4)\n",
    "        out = out.view(out.size(0), -1)  # 展平成一维\n",
    "        #print(out.shape)  # 调试信息，打印输出尺寸\n",
    "        out = self.fc(out)\n",
    "        return out\n",
    "    \n",
    "def ResNet18():\n",
    "    return ResNet(ResidualBlock)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "4002a59e-a765-4af9-981f-cb0359d22e49",
   "metadata": {},
   "outputs": [],
   "source": [
    "#检查GPU\n",
    "device = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "566fc53c-0fac-4e13-8b92-bf8d411e75a4",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 设置超参数\n",
    "EPOCH = 25\n",
    "pre_epoch = 0\n",
    "BATCH_SIZE = 8\n",
    "LR = 0.0004"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "4ac87c5f-d7dd-4210-948b-f7fbfb997ea2",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 准备数据集\n",
    "train_labeled_set = GetTrainLoader()  # label\n",
    "trainloader = DataLoader(train_labeled_set, batch_size=BATCH_SIZE, shuffle=True, num_workers=8, pin_memory=True)\n",
    "\n",
    "test_labeled_set = GetTestLoader()  # label\n",
    "testloader = DataLoader(test_labeled_set, batch_size=BATCH_SIZE, shuffle=False, num_workers=8, pin_memory=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "ccf89a4e-68fb-402d-940c-5cc1e9e920a3",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 定义 ResNet18\n",
    "net = ResNet18().to(device)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "836628d1-fd64-4217-b26a-2648006088a3",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 定义损失函数和优化器\n",
    "criterion = nn.CrossEntropyLoss()\n",
    "optimizer = optim.SGD(net.parameters(), lr=LR, momentum=0.8, weight_decay=5e-4)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "7d9b30c8-4759-4c81-8b3b-7002cfca4c79",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 创建 GradScaler 实例\n",
    "scaler = GradScaler()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "eaffd386-d14a-48c9-b206-d99d2d3eb3d0",
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Epoch: 1\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 1/25: 100%|██████████| 30/30 [00:01<00:00, 15.21batch/s, accuracy=tensor(60.8333), loss=1.09]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [1/25], Loss: 1.0874, Accuracy: 60.83%, Duration: 1.98s\n",
      "Waiting Test...\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n",
      "/root/miniconda3/lib/python3.12/site-packages/torch/nn/modules/conv.py:456: UserWarning: Plan failed with a cudnnException: CUDNN_BACKEND_EXECUTION_PLAN_DESCRIPTOR: cudnnFinalize Descriptor Failed cudnn_status: CUDNN_STATUS_NOT_SUPPORTED (Triggered internally at ../aten/src/ATen/native/cudnn/Conv_v8.cpp:919.)\n",
      "  return F.conv2d(input, weight, bias, self.stride,\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Test's accuracy is: 15.519%\n",
      "\n",
      "Epoch: 2\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 2/25: 100%|██████████| 30/30 [00:01<00:00, 20.69batch/s, accuracy=tensor(80.4167), loss=0.454]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [2/25], Loss: 0.4544, Accuracy: 80.42%, Duration: 1.45s\n",
      "Waiting Test...\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Test's accuracy is: 49.332%\n",
      "\n",
      "Epoch: 3\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 3/25: 100%|██████████| 30/30 [00:01<00:00, 20.67batch/s, accuracy=tensor(95.), loss=0.135]    "
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [3/25], Loss: 0.1353, Accuracy: 95.00%, Duration: 1.45s\n",
      "Waiting Test...\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Test's accuracy is: 93.628%\n",
      "\n",
      "Epoch: 4\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 4/25: 100%|██████████| 30/30 [00:01<00:00, 21.50batch/s, accuracy=tensor(99.1667), loss=0.0431]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [4/25], Loss: 0.0431, Accuracy: 99.17%, Duration: 1.40s\n",
      "Waiting Test...\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Test's accuracy is: 93.011%\n",
      "\n",
      "Epoch: 5\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 5/25: 100%|██████████| 30/30 [00:01<00:00, 21.49batch/s, accuracy=tensor(100.), loss=0.0205]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [5/25], Loss: 0.0205, Accuracy: 100.00%, Duration: 1.40s\n",
      "Waiting Test...\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Test's accuracy is: 93.217%\n",
      "\n",
      "Epoch: 6\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 6/25: 100%|██████████| 30/30 [00:01<00:00, 20.72batch/s, accuracy=tensor(98.3333), loss=0.0572]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [6/25], Loss: 0.0572, Accuracy: 98.33%, Duration: 1.45s\n",
      "Waiting Test...\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Test's accuracy is: 77.184%\n",
      "\n",
      "Epoch: 7\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 7/25: 100%|██████████| 30/30 [00:01<00:00, 22.05batch/s, accuracy=tensor(99.5833), loss=0.0185]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [7/25], Loss: 0.0185, Accuracy: 99.58%, Duration: 1.36s\n",
      "Waiting Test...\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Test's accuracy is: 94.347%\n",
      "\n",
      "Epoch: 8\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 8/25: 100%|██████████| 30/30 [00:01<00:00, 21.86batch/s, accuracy=tensor(99.5833), loss=0.0181]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [8/25], Loss: 0.0181, Accuracy: 99.58%, Duration: 1.37s\n",
      "Waiting Test...\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Test's accuracy is: 93.936%\n",
      "\n",
      "Epoch: 9\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 9/25: 100%|██████████| 30/30 [00:01<00:00, 22.24batch/s, accuracy=tensor(100.), loss=0.00941]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [9/25], Loss: 0.0094, Accuracy: 100.00%, Duration: 1.35s\n",
      "Waiting Test...\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Test's accuracy is: 95.170%\n",
      "\n",
      "Epoch: 10\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 10/25: 100%|██████████| 30/30 [00:01<00:00, 22.10batch/s, accuracy=tensor(100.), loss=0.00582]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [10/25], Loss: 0.0058, Accuracy: 100.00%, Duration: 1.36s\n",
      "Waiting Test...\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Test's accuracy is: 94.656%\n",
      "\n",
      "Epoch: 11\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 11/25: 100%|██████████| 30/30 [00:01<00:00, 21.38batch/s, accuracy=tensor(100.), loss=0.00536]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [11/25], Loss: 0.0054, Accuracy: 100.00%, Duration: 1.41s\n",
      "Waiting Test...\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Test's accuracy is: 94.347%\n",
      "\n",
      "Epoch: 12\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 12/25: 100%|██████████| 30/30 [00:01<00:00, 22.05batch/s, accuracy=tensor(100.), loss=0.00463]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [12/25], Loss: 0.0046, Accuracy: 100.00%, Duration: 1.36s\n",
      "Waiting Test...\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Test's accuracy is: 95.170%\n",
      "\n",
      "Epoch: 13\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 13/25: 100%|██████████| 30/30 [00:01<00:00, 21.84batch/s, accuracy=tensor(100.), loss=0.00537]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [13/25], Loss: 0.0054, Accuracy: 100.00%, Duration: 1.38s\n",
      "Waiting Test...\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Test's accuracy is: 93.628%\n",
      "\n",
      "Epoch: 14\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 14/25: 100%|██████████| 30/30 [00:01<00:00, 22.17batch/s, accuracy=tensor(100.), loss=0.0052] "
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [14/25], Loss: 0.0052, Accuracy: 100.00%, Duration: 1.36s\n",
      "Waiting Test...\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Test's accuracy is: 94.245%\n",
      "\n",
      "Epoch: 15\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 15/25: 100%|██████████| 30/30 [00:01<00:00, 22.17batch/s, accuracy=tensor(100.), loss=0.00401]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [15/25], Loss: 0.0040, Accuracy: 100.00%, Duration: 1.36s\n",
      "Waiting Test...\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Test's accuracy is: 95.067%\n",
      "\n",
      "Epoch: 16\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 16/25: 100%|██████████| 30/30 [00:01<00:00, 22.02batch/s, accuracy=tensor(99.5833), loss=0.019] "
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [16/25], Loss: 0.0190, Accuracy: 99.58%, Duration: 1.37s\n",
      "Waiting Test...\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Test's accuracy is: 94.450%\n",
      "\n",
      "Epoch: 17\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 17/25: 100%|██████████| 30/30 [00:01<00:00, 21.96batch/s, accuracy=tensor(100.), loss=0.00451]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [17/25], Loss: 0.0045, Accuracy: 100.00%, Duration: 1.37s\n",
      "Waiting Test...\n",
      "Test's accuracy is: 94.861%\n",
      "\n",
      "Epoch: 18\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 18/25: 100%|██████████| 30/30 [00:01<00:00, 22.17batch/s, accuracy=tensor(100.), loss=0.00283]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [18/25], Loss: 0.0028, Accuracy: 100.00%, Duration: 1.36s\n",
      "Waiting Test...\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Test's accuracy is: 94.450%\n",
      "\n",
      "Epoch: 19\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 19/25: 100%|██████████| 30/30 [00:01<00:00, 22.18batch/s, accuracy=tensor(100.), loss=0.00271]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [19/25], Loss: 0.0027, Accuracy: 100.00%, Duration: 1.36s\n",
      "Waiting Test...\n",
      "Test's accuracy is: 95.375%\n",
      "\n",
      "Epoch: 20\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 20/25: 100%|██████████| 30/30 [00:01<00:00, 21.88batch/s, accuracy=tensor(100.), loss=0.00315]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [20/25], Loss: 0.0032, Accuracy: 100.00%, Duration: 1.37s\n",
      "Waiting Test...\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Test's accuracy is: 95.170%\n",
      "\n",
      "Epoch: 21\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 21/25: 100%|██████████| 30/30 [00:01<00:00, 21.91batch/s, accuracy=tensor(100.), loss=0.00279]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [21/25], Loss: 0.0028, Accuracy: 100.00%, Duration: 1.37s\n",
      "Waiting Test...\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Test's accuracy is: 95.478%\n",
      "\n",
      "Epoch: 22\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 22/25: 100%|██████████| 30/30 [00:01<00:00, 22.04batch/s, accuracy=tensor(100.), loss=0.00229]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [22/25], Loss: 0.0023, Accuracy: 100.00%, Duration: 1.36s\n",
      "Waiting Test...\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Test's accuracy is: 95.375%\n",
      "\n",
      "Epoch: 23\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 23/25: 100%|██████████| 30/30 [00:01<00:00, 21.14batch/s, accuracy=tensor(100.), loss=0.00255]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [23/25], Loss: 0.0026, Accuracy: 100.00%, Duration: 1.42s\n",
      "Waiting Test...\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Test's accuracy is: 94.758%\n",
      "\n",
      "Epoch: 24\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 24/25: 100%|██████████| 30/30 [00:01<00:00, 19.21batch/s, accuracy=tensor(100.), loss=0.00208]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [24/25], Loss: 0.0021, Accuracy: 100.00%, Duration: 1.56s\n",
      "Waiting Test...\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Test's accuracy is: 95.478%\n",
      "\n",
      "Epoch: 25\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Epoch 25/25: 100%|██████████| 30/30 [00:01<00:00, 21.82batch/s, accuracy=tensor(100.), loss=0.00184]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [25/25], Loss: 0.0018, Accuracy: 100.00%, Duration: 1.38s\n",
      "Waiting Test...\n",
      "Test's accuracy is: 95.272%\n",
      "Total Training Time: 97.96s\n"
     ]
    }
   ],
   "source": [
    "# 记录每个epoch的训练损失、训练准确率和测试准确率\n",
    "train_losses = []\n",
    "train_accuracies = []\n",
    "test_accuracies = []\n",
    "\n",
    "# 训练过程\n",
    "total_start_time = time.time()  # 记录开始时间\n",
    "for epoch in range(pre_epoch, EPOCH):\n",
    "\n",
    "    print('\\nEpoch: %d' % (epoch + 1))\n",
    "    epoch_start_time = time.time()  # 记录每个epoch的开始时间\n",
    "    net.train()\n",
    "    sum_loss = 0.0\n",
    "    correct = 0.0\n",
    "    total = 0.0\n",
    "\n",
    "    # 使用tqdm显示训练进度\n",
    "    with tqdm(total=len(trainloader), desc=f'Epoch {epoch + 1}/{EPOCH}', unit='batch') as pbar:\n",
    "        for i, data in enumerate(trainloader, 0):\n",
    "            # 准备数据集\n",
    "            inputs, labels, im_idx = data\n",
    "            inputs, labels = inputs.to(device), labels.to(device)\n",
    "            optimizer.zero_grad()\n",
    "\n",
    "            # 使用autocast进行前向传播\n",
    "            with autocast():\n",
    "                outputs = net(inputs)\n",
    "                loss = criterion(outputs, labels)\n",
    "\n",
    "            # 使用scaler进行反向传播\n",
    "            scaler.scale(loss).backward()\n",
    "            scaler.step(optimizer)\n",
    "            scaler.update()\n",
    "\n",
    "            # 计算损失和准确率\n",
    "            sum_loss += loss.item()\n",
    "            _, predicted = torch.max(outputs.data, 1)\n",
    "            total += labels.size(0)\n",
    "            correct += predicted.eq(labels.data).cpu().sum()\n",
    "\n",
    "            # 更新进度条\n",
    "            pbar.set_postfix(loss=sum_loss / (i + 1), accuracy=100. * correct / total)\n",
    "            pbar.update(1)\n",
    "\n",
    "    epoch_end_time = time.time()  # 记录每个epoch的结束时间\n",
    "    epoch_duration = epoch_end_time - epoch_start_time  # 计算每个epoch的持续时间\n",
    "    epoch_accuracy = 100. * correct / total  # 计算训练准确度\n",
    "\n",
    "    # 记录训练损失和准确率\n",
    "    train_losses.append(sum_loss / len(trainloader))\n",
    "    train_accuracies.append(epoch_accuracy.cpu().numpy())\n",
    "\n",
    "    print(\n",
    "        f'Epoch [{epoch + 1}/{EPOCH}], Loss: {sum_loss / len(trainloader):.4f}, Accuracy: {epoch_accuracy:.2f}%, Duration: {epoch_duration:.2f}s')\n",
    "\n",
    "    # 测试集上的准确率\n",
    "    print('Waiting Test...')\n",
    "    with torch.no_grad():\n",
    "        correct = 0\n",
    "        total = 0\n",
    "        for data in testloader:\n",
    "            net.eval()\n",
    "            inputs, labels, _ = data\n",
    "            inputs, labels = inputs.to(device), labels.to(device)\n",
    "            outputs = net(inputs)\n",
    "            _, predicted = torch.max(outputs.data, 1)\n",
    "            total += labels.size(0)\n",
    "            correct += (predicted == labels).sum()\n",
    "        test_accuracy = 100. * correct.float() / total\n",
    "        test_accuracies.append(test_accuracy.cpu().numpy())\n",
    "        print('Test\\'s accuracy is: %.3f%%' % test_accuracy)\n",
    "\n",
    "    # 每个 epoch 结束后清理缓存\n",
    "    torch.cuda.empty_cache()\n",
    "\n",
    "total_end_time = time.time()  # 记录总训练时间的结束时间\n",
    "total_duration = total_end_time - total_start_time  # 计算总训练时间\n",
    "\n",
    "print(f'Total Training Time: {total_duration:.2f}s')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "64f90df9-2773-4f86-8cd6-c024141f2ae2",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Model weights saved to ./resnet18_weights_v1.pth\n",
      "Train has finished, total epoch is 25\n"
     ]
    }
   ],
   "source": [
    "# 训练结束后保存模型权重\n",
    "model_path = './resnet18_weights_v1.pth'\n",
    "torch.save(net.state_dict(), model_path)\n",
    "print(f'Model weights saved to {model_path}')\n",
    "\n",
    "print('Train has finished, total epoch is %d' % EPOCH)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "aa1b697a-6e96-44db-87c3-299b2139806e",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAABKEAAAHqCAYAAADcYF0vAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy80BEi2AAAACXBIWXMAAA9hAAAPYQGoP6dpAADMVElEQVR4nOzdd3iTZdvH8W+6Fx3Q0hYoUArK3oqAiAICDmQ5UHwZDlyIOB7Ho6DiwP3gxg0OFEVAVDaI4ARlCsiGAh2s7t3mfv+4TaB2t2mT0t/nOHIkuVfOJB13zlzneVkMwzAQERERERERERGpRm7ODkBERERERERERM5+SkKJiIiIiIiIiEi1UxJKRERERERERESqnZJQIiIiIiIiIiJS7ZSEEhERERERERGRaqcklIiIiIiIiIiIVDsloUREREREREREpNopCSUiIiIiIiIiItVOSSgREREREREREal2SkKJiFONGzeO5s2bV2rfJ554AovF4tiAREREpFbRuUTpDh48iMViYdasWc4ORURESSgRKZ7FYinXZc2aNc4O1SnGjRtHQECAs8MQERFxWTqXqD2aN29ervfKUYmsZ599loULF1Z4v507d2KxWPDx8SE5OdkhsYhIzbIYhmE4OwgRcT2ffvppofsff/wxK1as4JNPPim0/NJLLyU8PLzSj5OXl4fVasXb27vC++bn55Ofn4+Pj0+lH7+yxo0bx7x580hPT6/xxxYREakNdC7hGg4ePEh0dDQfffQR48aNK3abhQsXFjqnWbx4MZ9//jn/+9//CA0NtS/v1asXLVq0qHJMAQEBXH311RVOaj366KN8+OGHJCUl8cYbb3DLLbdUORYRqVkezg5ARFzTjTfeWOj+b7/9xooVK4os/7fMzEz8/PzK/Tienp6Vig/Aw8MDDw/9GRMREXFFOpeoPYYNG1bofkJCAp9//jnDhg2rdKmjoxmGwZw5c7jhhhs4cOAAn332mcsmoTIyMvD393d2GCIuSeV4IlJpF198Me3bt+fPP//koosuws/Pj//+978AfPPNN1xxxRU0atQIb29vYmJieOqppygoKCh0jH/3cbD1LXjppZd49913iYmJwdvbm/POO48NGzYU2re4Pg4Wi4WJEyeycOFC2rdvj7e3N+3atWPp0qVF4l+zZg3du3fHx8eHmJgY3nnnHYf3hvjqq6/o1q0b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79/P0qVLueaaa/D09Cx2G39//0Llc1VhtVrp2rUrzz77LF26dGHChAnceuutzJw5s9LHnD59OkFBQfZLVFSUQ2K1ixoBfeaZM9+dya+JuTxqhMMeSj2hREREXFelklB5eXl4e3sDsHLlSq66ypyhpHXr1oVms5MKUhJKRESk1jl27Bi///57keW///57oRnrHCUyMpK2bdsWWtamTRtiY2MBiIgwR1YnJhY+n0hMTLSv+7dHHnmElJQU++Xw4cMOj5uoEXDVQej/A/SaY15fdcChCSjDME73hFISSkRExOVUKgnVrl07Zs6cybp161ixYgWDBw8GIC4ujgYNNPVtpSkJJSIiUuvcddddxSZtjh49yl133eXwx+vduze7du0qtGz37t00a9YMMEv/IiIiWLVqlX19amoqv//+Oz179iz2mN7e3gQGBha6VAs3dwi/GJpfb147qATPJi03jYy8DAAiA1SOJyIi4moqlYR6/vnneeedd7j44ou5/vrr6dSpE2A2yrSV6UklKAklIiJS6+zYsYOuXbsWWd6lSxd27Njh8Me79957+e2333j22WfZu3cvc+bM4d1337UnvCwWC5MnT+bpp59m0aJFbNu2jTFjxtCoUSOGDRvm8HhciW0UVKB3IP5e/k6ORkRERP7NozI7XXzxxZw4cYLU1FRCQkLsyydMmICfn5/DgqtzlIQSERGpdby9vUlMTKRFixaFlsfHx+PhUalTrVKdd955LFiwgEceeYRp06YRHR3NjBkzGD16tH2bBx98kIyMDCZMmEBycjIXXnghS5cuxcfHx+HxuBL1gxIREXFtlTozysrKwjAMewLq0KFDLFiwgDZt2jBo0CCHBlin+NqSUMXPXCMiIiKuZ+DAgTzyyCN88803BAUFAZCcnMx///tfLr300mp5zCuvvJIrr7yyxPUWi4Vp06bVuVmL1Q9KRETEtVUqCTV06FBGjBjB7bffTnJyMj169MDT05MTJ07wyiuvcMcddzg6zrrB559moRoJJSIiUmu89NJLXHTRRTRr1owuXboAsHnzZsLDw/nkk0+cHF3dYktCqR+UiIiIa6pUT6iNGzfSp08fAObNm0d4eDiHDh3i448/5rXXXnNogHWKrRwv5yRY85wbi4iIiJRL48aN2bp1Ky+88AJt27alW7duvPrqq2zbto2oqChnh1enaCSUiIiIa6vUSKjMzEzq1asHwPLlyxkxYgRubm5ccMEFHDp0yKEB1ineDcDiDkYBZB8HP51AiYiI1Ab+/v5MmDDB2WHUefHp6gklIiLiyiqVhGrZsiULFy5k+PDhLFu2jHvvvReAY8eOVd+UvnWBxQ28w8yeUNmJSkKJiIjUIjt27CA2Npbc3NxCy6+66ionRVT3aCSUiIiIa6tUEmrq1KnccMMN3HvvvfTr14+ePXsC5qgoWy8EqSSf8NNJKBEREXF5+/fvZ/jw4Wzbtg2LxYJhGIDZHBygoKDAmeHVKeoJJSIi4toq1RPq6quvJjY2lj/++INly5bZl/fv35///e9/DguuTrL1hVISSkREpFa45557iI6O5tixY/j5+bF9+3bWrl1L9+7dWbNmjbPDqzMMw9BIKBERERdXqZFQABEREURERHDkyBEAmjRpwvnnn++wwOosexIqwblxiIiISLn8+uuvrF69mtDQUNzc3HBzc+PCCy9k+vTpTJo0iU2bNjk7xDohNSeVrPwsACLraSSUiIiIK6rUSCir1cq0adMICgqiWbNmNGvWjODgYJ566imsVqujY6xbfP9JQmVpJJSIiEhtUFBQYJ+wJTQ0lLg4czROs2bN2LVrlzNDq1Nso6CCfYLx8/RzcjQiIiJSnEqNhHr00Uf54IMPeO655+jduzcAP/30E0888QTZ2dk888wzDg2yTvGJMK9VjiciIlIrtG/fni1bthAdHU2PHj144YUX8PLy4t1336VFixbODq/OUD8oERER11epJNTs2bN5//33C8320rFjRxo3bsydd96pJFRVqCeUiIhIrfLYY4+RkZEBwLRp07jyyivp06cPDRo0YO7cuU6Oru6IT48H1A9KRETElVUqCXXq1Clat25dZHnr1q05depUlYOq05SEEhERqVUGDRpkv92yZUv+/vtvTp06RUhIiH2GPKl+akouIiLi+irVE6pTp0688cYbRZa/8cYbdOzYscpB1WlKQomIiNQaeXl5eHh48NdffxVaXr9+fSWgapiSUCIiIq6vUiOhXnjhBa644gpWrlxJz549AXNmmMOHD7N48WKHBljn2JJQOSfAmg9ulZ7AUERERKqZp6cnTZs2paCgwNmh1HnqCSUiIuL6KjUSqm/fvuzevZvhw4eTnJxMcnIyI0aMYPv27XzyySeOjrFu8Q4FixtgQM5xZ0cj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iIgTqB+UiIhI7aUkVG3iFWTOkgeQvM25sYiIiIg4wYGkAwC0CFY/KBERkdpGSajaxlaSl6SSPBEREal79iebI6HUlFxERKT2URKqtlFfKBEREanDVI4nIiJSeykJVdsoCSUiIiJ1mL0cTyOhREREah0loWobWxIq5S8wrM6NRURERKQGpeWkcTzzOGDOjiciIiK1i5JQtU29luDuA/kZkH7A2dGIiIiI1JgDyea5TwPfBgT5BDk5GhEREakoJaFqGzcPCGpn3lZJnoiIiNQh6gclIiJSuykJVRsFdzCvlYQSERGROkT9oERERGo3JaFqIzUnFxERkTrINhKqRbCSUCIiIrWRklC1kS0JlaQklIiIiNQd+5NVjiciIlKbKQlVG9mSUOn7IC/dubGIiIiI1BD7SCiV44mIiNRKSkLVRj5h4BMBGJCy3dnRiIiIiFQ7q2HlYPJBQEkoERGR2kpJqNpKfaFERESkDklITyA7Pxt3iztRgVHODkdEREQqQUmo2ipESSgREZG67rnnnsNisTB58mT7suzsbO666y4aNGhAQEAAI0eOJDEx0XlBOoitFC8qKApPd08nRyMiIiKVoSRUbaWRUCIiInXahg0beOedd+jYsWOh5ffeey/ffvstX331FT/++CNxcXGMGDHCSVE6zoGkA4BK8URERGozJaFqqzNnyDMM58YiIiIiNSo9PZ3Ro0fz3nvvERISYl+ekpLCBx98wCuvvEK/fv3o1q0bH330Eb/88gu//fabEyOuOntT8mAloURERGorJaFqq8DWYPGAvGTIOursaERERKQG3XXXXVxxxRUMGDCg0PI///yTvLy8Qstbt25N06ZN+fXXX2s6TIfan6yZ8URERGo7D2cHIJXk7g2B55qz4yVtBb8mzo5IREREasAXX3zBxo0b2bBhQ5F1CQkJeHl5ERwcXGh5eHg4CQkJJR4zJyeHnJwc+/3U1FSHxesotpFQ0SHRTo5EREREKksjoWoz9YUSERGpUw4fPsw999zDZ599ho+Pj8OOO336dIKCguyXqCjXm31OPaFERERqPyWhajMloUREROqUP//8k2PHjtG1a1c8PDzw8PDgxx9/5LXXXsPDw4Pw8HByc/+/vfuOj6LO/zj+2vRCKiUJkECACChNaaJSDpBEbDQFRAVUbOCJnIKotPP8gR0LwulR9AQpHiAKohRRRBCkCRIQEQwtgEgagSQk8/tjyJIlIQmkTLL7fj4e+8juzOzsZ2eyyTfvfL/fySQpKcnheceOHSM8PPyS+x09ejTJycn228GDB8v4nVyes+fOcjjVnH5AIZSIiEjlpeF4lZlCKBEREZfSpUsXduzY4bBs8ODBNGrUiFGjRhEZGYmnpyerVq2id+/eAOzZs4eEhATatWt3yf16e3vj7e1dprWXxIGkAwBU8apCVd+q1hYjIiIiV0whVGUWcj6EStkN2RnmPFEiIiLitAICAmjSpInDMn9/f6pWrWpf/uCDDzJixAhCQ0MJDAzkiSeeoF27dlx//fVWlFwq8g7Fs9lsFlcjIiIiV0ohVGXmWwu8QiDzFKTEQ0gLqysSERERi7355pu4ubnRu3dvMjIyiI2N5b333rO6rBLJnZRcQ/FEREQqN4VQlZnNZg7JO/6teYU8hVAiIiIuZ82aNQ6PfXx8mDJlClOmTLGmoDJgD6GCFUKJiIhUZpqYvLLTvFAiIiLi5H5PMkOo6JBoiysRERGRklAIVdkphBIREREnl3dOKBEREam8FEJVdgqhRERExIkZhqE5oURERJyEQqjKLvgawAZnj8HZ41ZXIyIiIlKqTp45SWpmKgB1g+taW4yIiIiUiEKoys7DH6rUN+8n7bC2FhEREZFSltsLqmZATXw8fCyuRkREREpCIZQzCNGQPBEREXFOmg9KRETEeSiEcgaaF0pERESclOaDEhERcR4KoZxBbgh1SiGUiIiIOJfcECo6ONriSkRERKSkFEI5g9wQKvkXyDlnbS0iIiIipWh/kobjiYiIOAuFUM6gSrQ5QXlOBqTutboaERERkVKj4XgiIiLOQyGUM7C5QVBT877mhRIREREnkZWdRUJyAqAQSkRExBkohHIWukKeiIiIOJmDKQfJNrLxdvcmvEq41eWIiIhICSmEchaanFxERESczP5T5nxQ0SHRuNnUbBUREans9NvcWdgnJ99hbR0iIiIipUTzQYmIiDgXhVDOIriJ+fX0H5CZbG0tIiIiIqUgN4SKDo62uBIREREpDQqhnIVXCPhFmveT1BtKREREKr/9SeZwPPWEEhERcQ4KoZxJsCYnFxEREeeh4XgiIiLORSGUM1EIJSIiIk5EIZSIiIhzUQjlTBRCiYiIiJNIyUjh5JmTgOaEEhERcRYKoZxJSG4ItQOMHGtrERERESmB/afM+aCq+VUjwDvA4mpERESkNCiEciYBV4GbF5xLg9MHrK5GRERE5IppKJ6IiIjzUQjlTNw8IOga8/4pDckTERGRyis3hNJQPBEREeehEMrZaF4oERERcQL7k8zheOoJJSIi4jwUQjkbhVAiIiLiBDQcT0RExPkohHI2eScnFxEREamkFEKJiIg4H4VQziaoqfk1dS+cS7e2FhEREZErkGPk2IfjaU4oERER56EQytn4hoFPDcCA5F+srkZERETksh1NPUpmdibuNncigyKtLkdERERKiUIoZ6R5oURERKQSyx2KVye4Dh5uHhZXIyIiIqVFIZQzyg2hTimEEhERkconN4TSUDwRERHnUiFCqClTplC3bl18fHxo27YtGzduvOS2H3zwAe3btyckJISQkBC6du1a6PYuST2hREREpBLTpOQiIiLOyfIQat68eYwYMYJx48axZcsWmjdvTmxsLMePHy9w+zVr1tC/f3+++eYb1q9fT2RkJN26dePw4cPlXHkFljeEMgxraxERERG5TLmTkiuEEhERcS6Wh1BvvPEGQ4YMYfDgwVx99dVMmzYNPz8/ZsyYUeD2s2fP5vHHH6dFixY0atSI//znP+Tk5LBq1apyrrwCC2oMNnfI/AvOHLG6GhEREZHLop5QIiIizsnSECozM5PNmzfTtWtX+zI3Nze6du3K+vXri7WP9PR0srKyCA0NLXB9RkYGKSkpDjen5+4DgQ3N+xqSJyIiIpWM5oQSERFxTpaGUH/++SfZ2dmEhYU5LA8LCyMxMbFY+xg1ahQ1a9Z0CLLymjhxIkFBQfZbZKSLXOZX80KJiIhIJXQm6wxH044C6gklIiLibCwfjlcSkyZNYu7cuSxatAgfH58Ctxk9ejTJycn228GDB8u5SovoCnkiIiJSCR1IOgBAoHcgob4F93QXERGRysnDyhevVq0a7u7uHDt2zGH5sWPHCA8PL/S5r732GpMmTWLlypU0a9bsktt5e3vj7e1dKvVWKrkhVPIOa+sQERERuQx554Oy2WwWVyMiIiKlydKeUF5eXrRs2dJhUvHcScbbtWt3yee98sorvPjiiyxfvpxWrVqVR6mVT3BT82tyPGRnWluLiIiISDFpPigRERHnZflwvBEjRvDBBx/w4YcfEh8fz2OPPcbp06cZPHgwAPfffz+jR4+2b//yyy8z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rV69+mXNjeXl5UV4eHi5/fz//vvvOXPmDH369OHDDz8sl9csjFVzMllNIZTk13Q8+EXC6QOw80WrqxEREREnpfmgRETKX3h4uP0WFBSEzWazP969ezcBAQF8+eWXtGzZEm9vb77//nv27dvHnXfeSVhYGFWqVKF169asXLnSYb8XD8ez2Wz85z//oWfPnvj5+RETE8OSJUvs6y8ejjdr1iyCg4P56quvaNy4MVWqVCEuLo6jR4/an3Pu3Dn+/ve/ExwcTNWqVRk1ahQDBw6kR48eRb7v6dOnc88993DfffcxY8aMfOsPHTpE//79CQ0Nxd/fn1atWvHjjz/a13/++ee0bt0aHx8fqlWrRs+ePR3e6+LFix32FxwczKxZswA4cOAANpuNefPm0bFjR3x8fJg9ezYnT56kf//+1KpVCz8/P5o2bconn3zisJ+cnBxeeeUVGjRogLe3N1FRUbz00ksAdO7cmWHDhjlsf+LECby8vFi1alWRx8QKCqEkP88q0Opd8378a5C009p6RERExCnlhlDRwZoPSkSchGHAudPW3Ayj1N7Gs88+y6RJk4iPj6dZs2akpaXRvXt3Vq1axdatW4mLi+P2228nISGh0P1MmDCBu+++m59//pnu3bszYMAA/vrrr0tun56ezmuvvcZ///tfvvvuOxISEhx6Zr388svMnj2bmTNnsm7dOlJSUvKFPwVJTU1lwYIF3Hvvvdx8880kJyezdu1a+/q0tDQ6duzI4cOHWbJkCdu3b2fkyJHk5OQAsHTpUnr27En37t3ZunUrq1atok2bNkW+7sWeffZZnnzySeLj44mNjeXs2bO0bNmSpUuXsnPnTh5++GHuu+8+Nm7caH/O6NGjmTRpEmPGjGHXrl3MmTOHsLAwAB566CHmzJlDRkaGffuPP/6YWrVq0blz58uurzx4WF2AVFC174DaPeDQYtj0KHT9zpwzSkRERCw1ceJEFi5cyO7du/H19eWGG27g5ZdfpmHDhvZtzp49yz/+8Q/mzp1LRkYGsbGxvPfee/ZGa0WRdzieiIhTyE6H+VWsee2708DDv1R29c9//pObb77Z/jg0NJTmzZvbH7/44ossWrSIJUuW5OuJk9egQYPo378/AP/3f//H22+/zcaNG4mLiytw+6ysLKZNm0b9+vUBGDZsGP/85z/t69955x1Gjx5t74X07rvvsmzZsiLfz9y5c4mJieGaa64BoF+/fkyfPp327dsDMGfOHE6cOMGmTZsIDQ0FoEGDBvbnv/TSS/Tr148JEybYl+U9HsU1fPhwevXq5bAsb8j2xBNP8NVXXzF//nzatGlDamoqb731Fu+++y4DBw4EoH79+tx0000A9OrVi2HDhvHZZ59x9913A2aPskGDBlXYYe5KFeTSWr4NHlXgxDrYl7+7ooiIiJS/b7/9lqFDh7JhwwZWrFhBVlYW3bp14/Tp0/ZtnnrqKT7//HMWLFjAt99+y5EjR/I1eisCDccTEamYWrVq5fA4LS2Np59+msaNGxMcHEyVKlWIj48vsidUs2bN7Pf9/f0JDAzk+PHjl9zez8/PHkABRERE2LdPTk7m2LFjDj2Q3N3dadmyZZHvZ8aMGdx77732x/feey8LFiwgNTUVgG3btnHttdfaA6iLbdu2jS5duhT5OkW5+LhmZ2fz4osv0rRpU0JDQ6lSpQpfffWV/bjGx8eTkZFxydf28fFxGF64ZcsWdu7cyaBBg0pca1lRTyi5NP9IaPZP2DICto00e0f51LC6KhEREZe2fPlyh8ezZs2iRo0abN68mQ4dOpCcnMz06dOZM2eOvSv+zJkzady4MRs2bOD666+3oux8DMNQCCUizsfdz+yRZNVrlxJ/f8ceVU8//TQrVqzgtddeo0GDBvj6+tKnTx8yMzML3Y+np6fDY5vNZh/iVtztjRIOM9y1axcbNmxg48aNjBo1yr48OzubuXPnMmTIEHx9fQvdR1HrC6qzoInHLz6ur776Km+99RaTJ0+madOm+Pv7M3z4cPtxLep1wRyS16JFCw4dOsTMmTPp3LkzderUKfJ5VlFPKCncVU9ASAvIPAVbni5ycxERESlfycnJAPb/3m7evJmsrCy6du1q36ZRo0ZERUWxfv16S2osyPHTx0nPSseGjaigKKvLEREpHTabOSTOilsZDr9at24dgwYNomfPnjRt2pTw8HAOHDhQZq9XkKCgIMLCwti0aZN9WXZ2Nlu2bCn0edOnT6dDhw5s376dbdu22W8jRoxg+vTpgNlja9u2bZecr6pZs2aFTvRdvXp1hwnU9+7dS3p60VeaX7duHXfeeSf33nsvzZs3p169evz666/29TExMfj6+hb62k2bNqVVq1Z88MEHzJkzhwceeKDI17WSQigpnJsHtP43YIMD/4XE1VZXVLgzR2H/fyEz2epKREREylxOTg7Dhw/nxhtvpEmTJgAkJibi5eVFcHCww7ZhYWEkJiYWuJ+MjAxSUlIcbmUtdz6o2oG18fbwLvPXExGRKxcTE8PChQvZtm0b27dv55577im0R1NZeeKJJ5g4cSKfffYZe/bs4cknn+TUqVOXnP8oKyuL//73v/Tv358mTZo43B566CF+/PFHfvnlF/r37094eDg9evRg3bp1/P777/zvf/+z//Nm3LhxfPLJJ4wbN474+Hh27NjByy+/bH+dzp078+6777J161Z++uknHn300Xy9ugoSExPDihUr+OGHH4iPj+eRRx7h2LFj9vU+Pj6MGjWKkSNH8tFHH7Fv3z42bNhgD89yPfTQQ0yaNAnDMByu2lcRKYSSolVrAzGPm/c3PQbZGYVvbwUjB357H75oBOvvh2VNIXFl0c8TERGpxIYOHcrOnTuZO3duifYzceJEgoKC7LfIyMhSqvDSNBRPRKTyeOONNwgJCeGGG27g9ttvJzY2luuuu67c6xg1ahT9+/fn/vvvp127dlSpUoXY2Fh8fHwK3H7JkiWcPHmywGCmcePGNG7cmOnTp+Pl5cXXX39NjRo16N69O02bNmXSpEm4u7sD0KlTJxYsWMCSJUto0aIFnTt3driC3euvv05kZCTt27fnnnvu4emnn8bPr+jhkS+88ALXXXcdsbGxdOrUyR6E5TVmzBj+8Y9/MHbsWBo3bkzfvn3zzavVv39/PDw86N+//yWPRUVhM0o6wLKSSUlJISgoiOTkZAIDA60up/LITIaljc2eRk3HQ9NxVld0QcqvsPFhOP6t+djNG3LOB2Uxj0GLV8DToitUiIhIheCMv/9zr4bz3XffER0dbV++evVqunTpwqlTpxx6Q9WpU4fhw4fz1FNP5dtXRkaGw+WdU1JSiIyMLNPj9a/v/sWYb8YwqMUgZt45s0xeQ0SkrJ09e5b9+/cTHR1d4f/4d0Y5OTk0btyYu+++mxdffNHqcixz4MAB6tevz6ZNm4oMBwv7ni2P9pJ6QknxeAXBdZPN+7/8nxn8WC0nC36ZCMuamQGUh79ZY+/jEDPU3GbvVPiyORz/ztJSRURESothGAwbNoxFixaxevVqhwAKoGXLlnh6ejrMH7Fnzx4SEhJo165dgfv09vYmMDDQ4VbW9p8yh+PVC1ZPKBERKZ4//viDDz74gF9//ZUdO3bw2GOPsX//fu655x6rS7NEVlYWiYmJvPDCC1x//fWW9E67XAqhpPii7oKIOMjJNIflWdmJ7uQmWN4Ktj9n9nqKiIXuO6HRk+AZCK3fhc4rwS8K0n6HlZ1g83A4V/TkcCIiIhXZ0KFD+fjjj5kzZw4BAQEkJiaSmJjImTNnAHPi1gcffJARI0bwzTffsHnzZgYPHky7du0qzJXxAH5P0nA8ERG5PG5ubsyaNYvWrVtz4403smPHDlauXEnjxo2tLs0S69atIyIigk2bNjFt2jSryykWD6sLkErEZoPWU2DpNXBsNfw8Fho9Bd6h5VfDudPm6+6ZbM4D5V0VrnsL6t6T/2oQ4V3g1h2w5R+w7z+w5y04sgyu/xCqF/yfYBERkYpu6tSpgDk/RV4zZ85k0KBBALz55pu4ubnRu3dvMjIyiI2N5b333ivnSgunOaFERORyRUZGsm7dOqvLqDA6depEZZthST2h5PJUqQdNzs8H9cu/YFFN+OE+c7hbWX/zH/0aljaB3W+YAVTdAXBrPEQPuPTlSD0Doe0H0GkZ+NaE1L2w8ibYOgqyz5ZtvSIiImXAMIwCb7kBFJhX05kyZQp//fUXp0+fZuHChYSHh1tX9EUyszM5mHwQgOiQ6CK2FhEREWehEEou39Ujoc2/Ibi5ORTuwMewsqM5cXn8a3D2xJXvO2UvfH0DfH4VLG8NSb9AxklYPwi+iYXTB8whdg2fhD9/hK+vhx+HmPNDASSuhuVt4IurzR5bW0eagVXNW+DWnRB9v/k4/hVY3hJO/lQaR0REREQuQ0JyAgYGvh6+hPmHWV2OiIiIlBOFUHL5bG7Q4GG4ZSvEboT6Q8CjCqTsga3PwOJa8H1fSFxpBj6XY9Mj5r5v/xUaj4Rv74AvGsP+DwGbGT51WgoJ8+HmtXD7b3D2GPz2vvl8rxC4aS7ctgviNsOfP8D+jy6sa/chdFgMPmGQvMsMsbaPgezMomsrKCAryL7psCQGltQvXkAmIiLiYvIOxbNdqjeziIiIOB2FUHLlbDao2hravg89j0Cb9yG0tRm6JMyH1TfD5zHmFezOHC14HznZcGwNHPgEDi4yeybVvRdOJ8Dvs+D075BxAoKaQLf10HIyHPkSat0BvuFmDQ0ehT8+MfcXeq05ZBDA3QeCW0DaAcfXrH0n3PoL1OkHRrY5rPCrNnBqe+HvN29AdvUo2DAo/zZp++HnMZcfkImIiLiQ3BBKQ/FERERci0IoKR2eAdBgCMRtNHtIxTxuzseU9rt5BbvFkfBdTzNAysk2n3NwISypC6v+Bj/cA2t7QfYZ2PSo2VPo6DLABtGDzNCmWlvzeekJ4F/nwmtXqWuGVhc7kwgHP4Vat+Vf510VbvwEbpoP3tUgabt5tb0dL17ouXSpgAwgsjekH4TU3xz3m/BpyQIyERERF2DvCRWsSclFRERcia6OJ6UvpIV5Fb1rX4WEBWZPoD9/gEOLzZtfFFRrBwnz8j/XOGcOZwOofiNkpkD0feDudXk1ZKXAt7ebQ/qqtrr0dlF3QfUOsOkxOLQIdoyFw5+ZYdPu1yH90IVtbR5weAlE9jIDJr8oM/wKaHBhm8sNyDp+cXnvqyApe2HDQMj4EzyD4PpZEHxN/u32TYdfJgE5ENYZWr8Hbp5mELZhEJzaCv7R0H1byWsSEREpxP6k/YCujCciIuJq1BNKyo6HH9QbCN3WQfed0HA4eIWaQU1BAVReniHwt9WQcRz8oxzX+UXB6T8uPE474LhNVip8E2cOu2s8oug6fcOg/f+g3cfmkLm/NsOWpxwDKDADsrV9zB5cJVHcgKy4SjpM0DMQmv0LbphT8louVtJ5tNIOwMpOsCAIlrVwndpERJxc3jmhRERExHUohJLyEXwNtHwTeh6Ga54vevusU7BrIvjVduxpBBDV2+yRdCYRDAN+mwZR/c4/L80MoCLioMkLxa/PZoPoAXDLdnDzKWRDA358GP74FFL3mrfDX8DhZXBkOWSfhRPrzEnIj62BQ5+DZ7C57MR6+HMDrO5W/IDsUnKHCv46zbxKYFR/c/mVDBP0DoUaN4GH/5XXcykVOSCryLWVJCA7cxT2f2xeHGBRJHx2UXhmVV3FWafaVJu4DM0JJSJiHZvNVuht/PjxJdr34sWLi739I488gru7OwsWLLji15TKRcPxpHy5+0BQAUPFCrL/Q+j4mXn/x4fMEKX2Hea8Sk0nwIobzXU1OkHMI+b9PW/ByY1w7vSFHktRd0GTYgRfAGn7IOds4dtknoR1d5n3Nz1a8DZHljo+XnGT4+MzR+H4dxDYEAIaml8DG5qhm62IbPjgQtj8pGNPrS8aQMu3zKGCJRkmWFI52XBirfn+3H3MebT+9rW5LrI3/DTMDMjy1pY3IAMzINv1f3DV0AsB2bE1zl3bxXIDsnqDzBo2DIK4TY7b5AZkXb6BpF2wdYQ599rZY47bufvBoc/g7Am45jkIvQ7cLuNHf97jFv8qxAyDBg8UXVfcFvMqlN/daQZ3Vw0tfF1JXc4xU20Vv7aSDjMuaF3DSSWrSUrNqTOnSDqbBEB0sEIoEZHydvTohYtGzZs3j7Fjx7Jnzx77sipVqpRLHenp6cydO5eRI0cyY8YM7rrrrnJ53UvJzMzEy+syp4GRy6aeUFL+fCOKt931MyC4qXm/7X/MACpXgyFwxz7zdv30C390NHke+meZ8xrl3oobQMGlr+J3MTdvCG4GVduaE5tXqQ8h10Jwc/CtZdZj8zT/eKrSwLx5hVx4fnoCJK6AX9+FzU/AN93gszowv4o5tOv7u2H7GLNHy8lN5hA+MAOotX3yDxVMP1w6QwVL4lITzR9eYq7PO49WXuURkFXk2uDyJsE/dwYSV8KGByHnHCy9Gr7vBacPnA+gbOb3oF8dc/hrdrp5hcnDn8HXbeHTUFhzG8S/Zg49zb1QQEEuPm6ntprzph1ceGW97gpbV5bHTLVVvtrW9YV6D115T8UC1nkmzLqyuqRUZedks2CX+d/uEJ8QfDwK630sIiJlITw83H4LCgrCZrM5LJs7dy6NGzfGx8eHRo0a8d5779mfm5mZybBhw4iIiMDHx4c6deowceJEAOrWrQtAz549sdls9seXsmDBAq6++mqeffZZvvvuOw4ePOiwPiMjg1GjRhEZGYm3tzcNGjRg+vTp9vW//PILt912G4GBgQQEBNC+fXv27dsHQKdOnRg+fLjD/nr06MGgQYPsj+vWrcuLL77I/fffT2BgIA8//DAAo0aN4qqrrsLPz4969eoxZswYsrIce3p//vnntG7dGh8fH6pVq0bPnj0B+Oc//0mTJk3yvdcWLVowZsyYQo+Hq6gQPaGmTJnCq6++SmJiIs2bN+edd96hTZs2l9x+wYIFjBkzhgMHDhATE8PLL79M9+7dy7FiKZHq7c0eP+mHAaOADWzm+urty7uy4gdkf1sOYZ0uf/+GYf5nP2UPpO4xv+beT91nBiNJ283bxXzCIfMvCj5m55f99CQYWQXPo5W278Lji+fRKqnccOzi2nLn0Wr/qdlLywoVuTYouGdb3knwjWzwqgq/TDSDphPrICfDcR8BV5kh6LFVcNtu2DEefGuaf7wn7YADc+HXt8zwNCvJ7KmX21vPMxhqdDC/n8P+ZoarNrdLH7czRy4ct8vtdVdaoV5Rx+xKLhyg2ipebTvGgnfwlfVULGCd588vXn5dUqoWxi/kyeVPcijFPM+nzp6i7lt1eSvuLXo1tvDnsIhIKTIMg/SsdEte28/TD5vNVqJ9zJ49m7Fjx/Luu+9y7bXXsnXrVoYMGYK/vz8DBw7k7bffZsmSJcyfP5+oqCgOHjxoD482bdpEjRo1mDlzJnFxcbi7uxf6WtOnT+fee+8lKCiIW265hVmzZjkENffffz/r16/n7bffpnnz5uzfv58///wTgMOHD9OhQwc6derE6tWrCQwMZN26dZw7d+6y3u9rr73G2LFjGTdunH1ZQEAAs2bNombNmuzYsYMhQ4YQEBDAyJEjAVi6dCk9e/bk+eef56OPPiIzM5Nly5YB8MADDzBhwgQ2bdpE69atAdi6dSs///wzCxda2GGgArE8hJo3bx4jRoxg2rRptG3blsmTJxMbG8uePXuoUaNGvu1/+OEH+vfvz8SJE7ntttuYM2cOPXr0YMuWLQUmjlIBubmbQ8fW9gFsOP6Re/6HZsvJ5nblrawDMpsNfKqbtxoXDdHLyTL/e5/6q2M4lbLH/A//2cSi93/mENjc4ds7wCvYDBi8gs1Q4dBn4F3drP+3D6BaW7OXVe42584AOea8VriZz7G5me+5sF9mOdnmH48FHi/M5ZuHQ807zv/BWo4BWUWuDYoIyHpDaGvzeyArBVJ2XVjvWxM8Asyegi3fNM9p8i7zKpTeVS9sZ3ODkOZmz7w/ZsMd+82A89gaOPYNnPjODKUOL7nQK8wr1Ayljq3JX5dZHGAzj5tPWOkdi+KqyKGiarsy5RR4up25qAeplKuF8QvpM78PxkXn+XDKYfrM78Ond3+qIEpEnEJ6VjpVJpbPcLaLpY1Ow9+rZPO8jhs3jtdff51evcyfydHR0ezatYt///vfDBw4kISEBGJiYrjpppuw2WzUqXPh92316tUBCA4OJjw8vNDX2bt3Lxs2bLAHM/feey8jRozghRdewGaz8euvvzJ//nxWrFhB165dAahX78LFLKZMmUJQUBBz587F09McFXPVVVdd9vvt3Lkz//jHPxyWvfDChbmF69aty9NPP20fNgjw0ksv0a9fPyZMmGDfrnnz5gDUrl2b2NhYZs6caQ+hZs6cSceOHR3qd2WWh1BvvPEGQ4YMYfDgwQBMmzaNpUuXMmPGDJ599tl827/11lvExcXxzDPPAPDiiy+yYsUK3n33XaZNm1autUsJRPYy/7C4+D/ffrXNAMqqP4asDMjcPCHwKvNW6zbHdZlJsOcds2dAUYxsSIkveN0v/7pw/9Rm2Pte/m3m+RbwRNv5UMr9fDCVJ6QycuBcWuE1pR+ExTXN7b6/+/x+3M25iXIy4dR2M0Rx94VT287PLdPrwnZnj5m9gL7rYQZLxjnzfRp57udc9NjINsObi4cuFlTb/6pCzhlY1SVP4GYzh7udPQpHvjR7jJxNNCdw/7zh+U3cIDvDXP7V9eDmZZ5HN88L92157uddb/OAvVO5dEAG/JU7N48NwruaE9qHdTHnD4t/zQzI/Gqbm+QNyC4Vnrm5m3NChV5nToyfc84cYnfsGzN0OrHW7G13aHHhxwzDPG4Zf8KJ782rVbr7gLs3nEuHEz+YPbbcvM052ryrw+mDZsCVutecsw2bGbD61T4ffJ5/n3m/2i56nJMDP/29kGNmmL0Ba3Q1a/IOMT87Ro558wqF5HhIPwLkmCGsT5gZ/rr7w6mfzw9Fs5kXEfAJOx9q2C4KZd3yLzMM+OmJwmu70sCzpGFoWYaxZVqbxYGnlJrsnGyeXP5kvgAKwMDAho3hy4dzZ8M7cbfiH1AiIgLA6dOn2bdvHw8++CBDhgyxLz937hxBQUEADBo0iJtvvpmGDRsSFxfHbbfdRrdu3S77tWbMmEFsbCzVqlUDoHv37jz44IOsXr2aLl26sG3bNtzd3enYsWOBz9+2bRvt27e3B1BXqlWr/FcrnzdvHm+//Tb79u0jLS2Nc+fOERgY6PDaeY/PxYYMGcIDDzzAG2+8gZubG3PmzOHNN98sUZ3OxNIQKjMzk82bNzN69Gj7Mjc3N7p27cr69esLfM769esZMcLxqmKxsbGXNQO/VBCRvaDWnRcmPfaNMHsYWd0ArYgBmVcw1Chm76s2H5i9BTKTIPOU2dMl8/wt66Kvufdz55y6JONCsHOlMk6YX09tLXj9ibV5tj0OyTvyb3Posyt//cKcO//+0y8xjCjv8tw5li528sfSrwug/hD4awt0/tpxeVRvc8L7M+PNP9DzXiWysHV5uXlA1dbm7eqRZm+8vzbD7smQMK/o2rLPwI5xBa878oXj48/yBBO/z3RcV2DweYXOHIL/mY0kvryu4G0O/Nfx8ZI8/5VKmOu47rM6lJr0gzDPGzBgWTPHQBcgKxUOfgp4mJ9Ld1/4rK4Z1OSGobhBxjHzKp6Lo8x9Gcb5rznm14uX5WTBudSia/tfiBmqrursWJuRbf4sPPaNGaqmJ5hXh1zeCrIzIWW3GTbavCDtV3P+uxXtudCL0nbp+5mnigiKzwee59JKHI7l+NYG1BvKCmsT1tqH4BXEwOBgykHWJqylU91O5VeYiEgZ8PP0I210Ef+gLcPXLom0NLPuDz74gLZt2zqsyx1ad91117F//36+/PJLVq5cyd13303Xrl359NNPi/062dnZfPjhhyQmJuLh4eGwfMaMGXTp0gVf38Lbh0Wtd3NzwzAc//lx8bxOAP7+jj3H1q9fz4ABA5gwYQKxsbH23lavv/56sV/79ttvx9vbm0WLFuHl5UVWVhZ9+vQp9DmuxNIQ6s8//yQ7O5uwMMf/cIaFhbF79+4Cn5OYmFjg9omJBQ9VysjIICPjwvwpKSlF/bEt5crN/crmViprFTEgK+5QwXqDL7/OnGyzRxI5F3qN5L1vZOdflnv/z/Ww/v6iX+Pa183hYxf3YLL3Ysrbu+n849zeTbm9sNw8LvSOsuW5f6nlSTtgy/Cia2s9DUJbYj+uuX/AF/TY/svs/B/4xjnz2OVk5fl6/r6RVfDynCyztqNfFl1b4srLv0pkYesK4+YJ1a6HmEeLF0KFtgG/WmaPLc8Q8Ao0ezWdOWJejQ/DDC1sHmBknv8eq0jczvdOczfvG1lmCAN5vpfI8z2fN+i5Ujnml+wzBa/OOJln0wwzjMrlEIaegaxTJaijALk9GtMPFrw+9dc826bCmcMXHucNlzNPQdrvpVubZ7DjUDy47CA2q2ZvYEPp1iXFcjS1eBf9KO52IiIVmc1mK/GQOKuEhYVRs2ZNfv/9dwYMGHDJ7QIDA+nbty99+/alT58+xMXF8ddffxEaGoqnpyfZ2YX/43rZsmWkpqaydetWh3mjdu7cyeDBg0lKSqJp06bk5OTw7bff2ofj5dWsWTM+/PBDsrKyCuwNVb16dYerAGZnZ7Nz507+9re/FVrbDz/8QJ06dXj++QsXt/rjjz/yvfaqVavso7ku5uHhwcCBA5k5cyZeXl7069evyODKlVg+HK+sTZw40WGspkixVbSArCyHCrq5g9sV/mD0j4btzxUdjjV8svxDvBodYfdrRddW/6Hyr+3YmuKFUBdfJTKvBkPMW0EKW1eU4gae3X64vONm5Jghj5GdZ795gz4KX37ie3NIZlE6LTPP/cVDR4ua3+xyGIZjMHV8DXwTW/TzbpxvBn3kCXfzhr1cFPzaA99sLvQiyvtecr+6FdDT6Pyyk5sKvrrcxdp8YA7VLCiILjKUzhvS5hQQ3BoFL0veBbsmFl1bk/NzM5QgiM2qMxh4pujXklIXEVC8i34UdzsRESk7EyZM4O9//ztBQUHExcWRkZHBTz/9xKlTpxgxYgRvvPEGERERXHvttbi5ubFgwQLCw8MJDg4GzDmUVq1axY033oi3tzchISH5XmP69Onceuut9nmUcl199dU89dRTzJ49m6FDhzJw4EAeeOAB+8Tkf/zxB8ePH+fuu+9m2LBhvPPOO/Tr14/Ro0cTFBTEhg0baNOmDQ0bNqRz586MGDGCpUuXUr9+fd544w2SkpKKfP8xMTEkJCQwd+5cWrduzdKlS1m0aJHDNuPGjaNLly7Ur1+ffv36ce7cOZYtW8aoUaPs2zz00EM0btwYgHXr1l3mWXBuloZQ1apVw93dnWPHjjksP3bs2CUnMgsPD7+s7UePHu0wfC8lJYXIyMgSVi5ikYo4VLAiTzRfkWuryFeJLKvjZnMDjxL8F6jmbcU7ZuHdyv6c2mxmb6lcYV2KV1tkr/L/fgtoCD+/UDa9KEsqJ9scHllUbdEDzYclCWLVE9oy7aPaUzuwNodTDhc4L5QNG7UDa9M+yoKfdyIi4uChhx7Cz8+PV199lWeeeQZ/f3+aNm3K8OHDAfPKca+88gp79+7F3d2d1q1bs2zZMtzczOkFXn/9dUaMGMEHH3xArVq1OHDggMP+jx07xtKlS5kzZ06+13Zzc6Nnz55Mnz6doUOHMnXqVJ577jkef/xxTp48SVRUFM899xwAVatWZfXq1TzzzDN07NgRd3d3WrRowY03mv+AeuCBB9i+fTv3338/Hh4ePPXUU0X2ggK44447eOqppxg2bBgZGRnceuutjBkzhvHjx9u36dSpEwsWLODFF19k0qRJBAYG0qFDB4f9xMTEcMMNN/DXX3/lG9ro6mzGxQMly1nbtm1p06YN77zzDgA5OTlERUUxbNiwAicm79u3L+np6Xz++ef2ZTfccAPNmjUr1sTkKSkpBAUFkZyc7DC5mEilkpNdsYYKQsGXWPeLtHai+VwVtTb7VcGgwKDHyiuWQcU8bhX5mKm2K1NOten3/+Up7eOVe3U8wCGIsp0/z7o6nohUVmfPnmX//v1ER0fj4+NjdTlSQRiGQUxMDI8//ni+Oa2tVtj3bHm0lywPoebNm8fAgQP597//TZs2bZg8eTLz589n9+7dhIWFcf/991OrVi0mTjS76//www907NiRSZMmceuttzJ37lz+7//+jy1bttCkSZMiX0+NUJEyVBHDsVwVtbaKGPTkVRGPW0U+ZqrtypRDbfr9f3nK4ngtjF/Ik8ufdJikPDIwkslxkxVAiUilpRBKLnbixAnmzp3L6NGjOXjwYIFDEq1kdQhl+ZxQffv25cSJE4wdO5bExERatGjB8uXL7ZOPJyQk2Lv2gdnrac6cObzwwgs899xzxMTEsHjx4mIFUCJSxiraPFp5VdTaKuIk+HlVxONWkY+ZanO+2qTU9Grcizsb3snahLUcTT1KREAE7aPa467zLCIiTqRGjRpUq1aN999/v8IFUBWB5T2hypv+EyoiIuJ69Pv/8uh4iYgUj3pCSWVjdU8ot6I3ERERERERERERKRmFUCIiIiIiIiIiUuYsnxNKRERERFzP37/8O0v2LOGP5D/Y+shWWoS3AKDu5Lp4e3jj6+ELwOibRtO3Sd98z19zYA23zL6FhlUb2petf3A9vp6+rN6/mmdXPktaZho2m41bY25lUtdJuNn0/1cRKRsuNsuNVGJWf68qhBIRERGRctfn6j6MvHEkN824Kd+6eX3m2UOpwjSs2pBtj27LtzzEJ4S5feZSL6QeZ8+dpetHXflo+0cMajGo5IWLiOTh6ekJQHp6Or6+vhZXI1K09PR04ML3bnlTCCUiIiIi5a5DnQ5ltu9rI6613/fx8KFFeAsOJB0os9cTEdfl7u5OcHAwx48fB8DPzw+bzWZxVSL5GYZBeno6x48fJzg4GHd3a65OqxBKRERERCqU+xfdj4FBm5ptmNR1EtX9qxe43b5T+7ju39fh7ubO4BaDebz14/m2SUxL5NNdn/LFPV+Uddki4qLCw8MB7EGUSEUWHBxs/561gkIoEREREakwvhv8HVFBUWRlZ/HC6hcYuHggywYsy7fddRHXceipQwT5BHEo5RDdZ3enml817r7mbvs2KRkp3P7J7Yy8cSStarYqz7chIi7EZrMRERFBjRo1yMrKsrockUvy9PS0rAdULoVQIiIiIlJhRAVFAeDp7snw64dz1btXFbhdoHeg/X7twNr0b9KftX+stYdQqRmpxH0cx50N72REuxFlX7iIuDx3d3fL/8AXqeh0iRARERERqRBOZ54m6WyS/fEnOz/h2vBrC9z2aOpRcowcwAycvtj7hX0uqLTMNOJmxxHXII4XOrxQ5nWLiIhI8agnlIiIiIiUu0c+f4Sle5eSmJZI7MexBHgF8PV9X9N7fm+yc7IxMKgXUo+Pen5kf85DSx7ijoZ3cEfDO/hf/P+Y+tNUPNw8OJdzjruuvovBLQYD8NaGt9h4eCOnM0+zMH4hAHddfRfPd3jekvcqIiIiJpthGIbVRZSnlJQUgoKCSE5OJjAwsOgniIiISKWn3/+XR8dLRETE9ZTH73+X6wmVm7mlpKRYXImIiIiUl9zf+y72v7crpvaSiIiI6ymP9pLLhVCpqakAREZGWlyJiIiIlLfU1FSCgoKsLqPCU3tJRETEdZVle8nlhuPl5ORw5MgRAgICsNlspKSkEBkZycGDB9Xd3CI6B9bTObCezoH1dA6sV5bnwDAMUlNTqVmzJm5uui5LUdReqnh0Dqync2A9nQNr6fhbr6zPQXm0l1yuJ5Sbmxu1a9fOtzwwMFAfJIvpHFhP58B6OgfW0zmwXlmdA/WAKj61lyounQPr6RxYT+fAWjr+1ivLc1DW7SX9K1BERERERERERMqcQigRERERERERESlzLh9CeXt7M27cOLy9va0uxWXpHFhP58B6OgfW0zmwns5BxaVzYz2dA+vpHFhP58BaOv7Wc4Zz4HITk4uIiIiIiIiISPlz+Z5QIiIiIiIiIiJS9hRCiYiIiIiIiIhImVMIJSIiIiIiIiIiZc7lQ6gpU6ZQt25dfHx8aNu2LRs3brS6JJcxfvx4bDabw61Ro0ZWl+XUvvvuO26//XZq1qyJzWZj8eLFDusNw2Ds2LFERETg6+tL165d2bt3rzXFOqmizsGgQYPyfS7i4uKsKdYJTZw4kdatWxMQEECNGjXo0aMHe/bscdjm7NmzDB06lKpVq1KlShV69+7NsWPHLKrY+RTnHHTq1Cnf5+DRRx+1qGJRW8k6aiuVP7WVrKe2kvXUXrKeM7eXXDqEmjdvHiNGjGDcuHFs2bKF5s2bExsby/Hjx60uzWVcc801HD161H77/vvvrS7JqZ0+fZrmzZszZcqUAte/8sorvP3220ybNo0ff/wRf39/YmNjOXv2bDlX6ryKOgcAcXFxDp+LTz75pBwrdG7ffvstQ4cOZcOGDaxYsYKsrCy6devG6dOn7ds89dRTfP755yxYsIBvv/2WI0eO0KtXLwurdi7FOQcAQ4YMcfgcvPLKKxZV7NrUVrKe2krlS20l66mtZD21l6zn1O0lw4W1adPGGDp0qP1xdna2UbNmTWPixIkWVuU6xo0bZzRv3tzqMlwWYCxatMj+OCcnxwgPDzdeffVV+7KkpCTD29vb+OSTTyyo0PldfA4MwzAGDhxo3HnnnZbU44qOHz9uAMa3335rGIb5Pe/p6WksWLDAvk18fLwBGOvXr7eqTKd28TkwDMPo2LGj8eSTT1pXlNiprWQttZWspbaS9dRWqhjUXrKeM7WXXLYnVGZmJps3b6Zr1672ZW5ubnTt2pX169dbWJlr2bt3LzVr1qRevXoMGDCAhIQEq0tyWfv37ycxMdHhMxEUFETbtm31mShna9asoUaNGjRs2JDHHnuMkydPWl2S00pOTgYgNDQUgM2bN5OVleXwOWjUqBFRUVH6HJSRi89BrtmzZ1OtWjWaNGnC6NGjSU9Pt6I8l6a2UsWgtlLFobZSxaG2UvlSe8l6ztRe8rC6AKv8+eefZGdnExYW5rA8LCyM3bt3W1SVa2nbti2zZs2iYcOGHD16lAkTJtC+fXt27txJQECA1eW5nMTERIACPxO566TsxcXF0atXL6Kjo9m3bx/PPfcct9xyC+vXr8fd3d3q8pxKTk4Ow4cP58Ybb6RJkyaA+Tnw8vIiODjYYVt9DspGQecA4J577qFOnTrUrFmTn3/+mVGjRrFnzx4WLlxoYbWuR20l66mtVLGorVQxqK1UvtResp6ztZdcNoQS691yyy32+82aNaNt27bUqVOH+fPn8+CDD1pYmYh1+vXrZ7/ftGlTmjVrRv369VmzZg1dunSxsDLnM3ToUHbu3Kn5VSx0qXPw8MMP2+83bdqUiIgIunTpwr59+6hfv355lyliGbWVRPJTW6l8qb1kPWdrL7nscLxq1arh7u6ebwb/Y8eOER4eblFVri04OJirrrqK3377zepSXFLu970+ExVLvXr1qFatmj4XpWzYsGF88cUXfPPNN9SuXdu+PDw8nMzMTJKSkhy21+eg9F3qHBSkbdu2APoclDO1lSoetZWspbZSxaS2UtlRe8l6zthectkQysvLi5YtW7Jq1Sr7spycHFatWkW7du0srMx1paWlsW/fPiIiIqwuxSVFR0cTHh7u8JlISUnhxx9/1GfCQocOHeLkyZP6XJQSwzAYNmwYixYtYvXq1URHRzusb9myJZ6eng6fgz179pCQkKDPQSkp6hwUZNu2bQD6HJQztZUqHrWVrKW2UsWktlLpU3vJes7cXnLp4XgjRoxg4MCBtGrVijZt2jB58mROnz7N4MGDrS7NJTz99NPcfvvt1KlThyNHjjBu3Djc3d3p37+/1aU5rbS0NIdkfP/+/Wzbto3Q0FCioqIYPnw4//rXv4iJiSE6OpoxY8ZQs2ZNevToYV3RTqawcxAaGsqECRPo3bs34eHh7Nu3j5EjR9KgQQNiY2MtrNp5DB06lDlz5vDZZ58REBBgn7cgKCgIX19fgoKCePDBBxkxYgShoaEEBgbyxBNP0K5dO66//nqLq3cORZ2Dffv2MWfOHLp3707VqlX5+eefeeqpp+jQoQPNmjWzuHrXo7aStdRWKn9qK1lPbSXrqb1kPaduL1l7cT7rvfPOO0ZUVJTh5eVltGnTxtiwYYPVJbmMvn37GhEREYaXl5dRq1Yto2/fvsZvv/1mdVlO7ZtvvjGAfLeBAwcahmFeenjMmDFGWFiY4e3tbXTp0sXYs2ePtUU7mcLOQXp6utGtWzejevXqhqenp1GnTh1jyJAhRmJiotVlO42Cjj1gzJw5077NmTNnjMcff9wICQkx/Pz8jJ49expHjx61rmgnU9Q5SEhIMDp06GCEhoYa3t7eRoMGDYxnnnnGSE5OtrZwF6a2knXUVip/aitZT20l66m9ZD1nbi/ZDMMwyibeEhERERERERERMbnsnFAiIiIiIiIiIlJ+FEKJiIiIiIiIiEiZUwglIiIiIiIiIiJlTiGUiIiIiIiIiIiUOYVQIiIiIiIiIiJS5hRCiYiIiIiIiIhImVMIJSIiIiIiIiIiZU4hlIiIiIiIiIiIlDmFUCIiBbDZbCxevNjqMkREREQqJLWVRORKKIQSkQpn0KBB2Gy2fLe4uDirSxMRERGxnNpKIlJZeVhdgIhIQeLi4pg5c6bDMm9vb4uqEREREalY1FYSkcpIPaFEpELy9vYmPDzc4RYSEgKY3b+nTp3KLbfcgq+vL/Xq1ePTTz91eP6OHTvo3Lkzvr6+VK1alYcffpi0tDSHbWbMmME111yDt7c3ERERDBs2zGH9n3/+Sc+ePfHz8yMmJoYlS5bY1506dYoBAwZQvXp1fH19iYmJydcQFBERESkraiuJSGWkEEpEKqUxY8bQu3dvtm/fzoABA+jXrx/x8fEAnD59mtjYWEJCQti0aRMLFixg5cqVDg2nqVOnMnToUB5++GF27NjBkiVLaNCggcNrTJgwgbvvvpuff/6Z7t27M2DAAP766y/76+/atYsvv/yS+Ph4pk6dSrVq1crvAIiIiIgUQm0lEamQDBGRCmbgwIGGu7u74e/v73B76aWXDMMwDMB49NFHHZ7Ttm1b47HHHjMMwzDef/99IyQkxEhLS7OvX7p0qeHm5mYkJiYahmEYNWvWNJ5//vlL1gAYL7zwgv1xWlqaARhffvmlYRiGcfvttxuDBw8unTcsIiIichnUVhKRykpzQolIhfS3v/2NqVOnOiwLDQ2132/Xrp3Dunbt2rFt2zYA4uPjad68Of7+/vb1N954Izk5OezZswebzcaRI0fo0qVLoTU0a9bMft/f35/AwECOHz8OwGOPPUbv3r3ZsmUL3bp1o0ePHtxwww1X9F5FRERELpfaSiJSGSmEEpEKyd/fP1+X79Li6+tbrO08PT0dHttsNnJycgC45ZZb+OOPP1i2bBkrVqygS5cuDB06lNdee63U6xURERG5mNpKIlIZaU4oEamUNmzYkO9x48aNAWjcuDHbt2/n9OnT9vXr1q3Dzc2Nhg0bEhAQQN26dVm1alWJaqhevToDBw7k448/ZvLkybz//vsl2p+IiIhIaVFbSUQqIvWEEpEKKSMjg8TERIdlHh4e9gktFyxYQKtWrbjpppuYPXs2GzduZPr06QAMGDCAcePGMXDgQMaPH8+JEyd44oknuO+++wgLCwNg/PjxPProo9SoUYNbbrmF1NRU1q1bxxNPPFGs+saOHUvLli255ppryMjI4IsvvrA37ERERETKmtpKIlIZKYQSkQpp+fLlREREOCxr2LAhu3fvBsyrscydO5fHH3+ciIgIPvnkE66++moA/Pz8+Oqrr3jyySdp3bo1fn5+9O7dmzfeeMO+r4EDB3L27FnefPNNnn76aapVq0afPn2KXZ+XlxejR4/mwIED+Pr60r59e+bOnVsK71xERESkaGoriUhlZDMMw7C6CBGRy2Gz2Vi0aBE9evSwuhQRERGRCkdtJRGpqDQnlIiIiIiIiIiIlDmFUCIiIiIiIiIiUuY0HE9ERERERERERMqcekKJiIiIiIiIiEiZUwglIiIiIiIiIiJlTiGUiIiIiIiIiIiUOYVQIiIiIiIiIiJS5hRCiYiIiIiIiIhImVMIJSIiIiIiIiIiZU4hlIiIiIiIiIiIlDmFUCIiIiIiIiIiUuYUQomIiIiIiIiISJn7f0vjEc4PHnFNAAAAAElFTkSuQmCC",
      "text/plain": [
       "<Figure size 1200x500 with 2 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# 绘制训练损失和准确率变化曲线\n",
    "epochs = range(1, EPOCH + 1)\n",
    "plt.figure(figsize=(12, 5))\n",
    "\n",
    "# 训练损失曲线\n",
    "plt.subplot(1, 2, 1)\n",
    "plt.plot(epochs, train_losses, 'orange', label='Training Loss')\n",
    "# 每五个epoch标记一个点并显示数值\n",
    "for i in range(0, EPOCH, 2):\n",
    "    plt.scatter(epochs[i], train_losses[i], color='orange')\n",
    "    plt.text(epochs[i], train_losses[i] + 0.02, f'{train_losses[i]:.2f}', ha='left', va='top', color='orange', fontsize=8)\n",
    "plt.title('Training Loss')\n",
    "plt.xlabel('Epochs')\n",
    "plt.ylabel('Loss')\n",
    "plt.legend()\n",
    "plt.savefig('training_loss1.png')  # 保存训练损失图像\n",
    "\n",
    "# 训练和测试准确率曲线\n",
    "plt.subplot(1, 2, 2)\n",
    "plt.plot(epochs, train_accuracies, 'orange', label='Training Accuracy')\n",
    "plt.plot(epochs, test_accuracies, 'green', label='Test Accuracy')\n",
    "# 每五个epoch标记一个点并显示数值\n",
    "for i in range(0, EPOCH, 2):\n",
    "    plt.scatter(epochs[i], train_accuracies[i], color='orange')\n",
    "    plt.text(epochs[i], train_accuracies[i] + 2, f'{train_accuracies[i]:.2f}', ha='left', va='top', color='orange', fontsize=8)\n",
    "    plt.scatter(epochs[i], test_accuracies[i], color='green')\n",
    "    plt.text(epochs[i], test_accuracies[i] - 2, f'{test_accuracies[i]:.2f}', ha='left', va='top', color='green', fontsize=8)\n",
    "plt.title('Training and Test Accuracy')\n",
    "plt.xlabel('Epochs')\n",
    "plt.ylabel('Accuracy (%)')\n",
    "plt.legend()\n",
    "plt.savefig('training_and_test_accuracy1.png')  # 保存训练和测试准确率图像\n",
    "\n",
    "plt.tight_layout()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "af3ee6f4-2979-4f29-9694-c98ed8b51e3a",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 最终测试并保存结果\n",
    "net.eval()\n",
    "with torch.no_grad():\n",
    "    with open(\"test.txt\", 'w') as f:\n",
    "        for idx, (inputs, targets, im_ids) in enumerate(trainloader):\n",
    "            inputs, targets = inputs.to(device), targets.to(device)\n",
    "            outputs = net(inputs)\n",
    "            _, pred = outputs.topk(1, 1, True, True)\n",
    "            pred = pred.t()\n",
    "            pred = pred.cpu().numpy().tolist()\n",
    "            for i in range(inputs.shape[0]):\n",
    "                f.write(im_ids[i] + ' ' + str(pred[0][i]) + '\\n')\n",
    "    f.close()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
